#pragma once

#include <iostream>
#include <string>
#include <cstring>
#include <sys/types.h>
#include <sys/socket.h>

//序列化和反序列化协议

#define MYSELF 1
#define SPACE " "
#define SPACE_LEN strlen(SPACE)

#define SEP "/r/n"
#define SEP_LEN strlen(SEP)


class Request
{
public: 
    Request(){}
    Request(int x, int y, char op) : _x(x), _y(y), _op(op)
    {}
    //x op y
    std::string Serialize()
    {
#ifdef MYSELF
        std::string s;
        s += std::to_string(_x);
        s += SPACE;
        s += _op;
        s += SPACE;
        s += std::to_string(_y);
        return s;
#else
    //TODO
#endif
    }

    bool Deserialize(const std::string& s)
    {
#ifdef MYSELF
        int left = s.find(SPACE);
        if(left == std::string::npos) //没找到空格
            return false;
        int right = s.rfind(SPACE); //从后向前找的第一个空格
        if(right == std::string::npos || left == right) //没找到空格或重复
            return false;
        //切割
        _x = atoi(s.substr(0,left).c_str());
        _y = atoi(s.substr(right + SPACE_LEN).c_str());
        if(left+SPACE_LEN > s.size())
            return false;
        else
            _op = s[left+SPACE_LEN];
        return true;
#else
    //TODO
#endif
    }

public:
    //外边还要用呢，反序列化后的值存在里面
    int _x;
    int _y;
    char _op;
};


class Response
{
public: 
    Response(){}
    Response(int code, int res) : _res(res),_code(code)
    {}
    //code res
    std::string Serialize()
    {
#ifdef MYSELF
        std::string s;
        s += std::to_string(_code);
        s += SPACE;
        s += std::to_string(_res);
        return s;
#else
    //TODO
#endif
    }

    bool Deserialize(const std::string& s)
    {
#ifdef MYSELF
        int find = s.find(SPACE);
        if(find == std::string::npos) //没找到空格
            return false;
        
        //切割
        _code = atoi(s.substr(0,find).c_str());
        _res = atoi(s.substr(find+SPACE_LEN).c_str());
        
        return true;
#else
    //TODO
#endif
    }

public:
    //外边还要用呢，反序列化后的值存在里面
    int _code;  //退出码
    int _res;   //结果
};

//收发消息的临时方案...
bool Recv(int sock,std::string* out)
{
    char buffer[1024];
    ssize_t s = recv(sock,buffer,sizeof(buffer)-1,0);
    if(s > 0){
        buffer[s] = 0;
        *out = buffer;
    }
    else if(s == 0)
    {
        //std::cout << "client quit" << std::endl;
        return false;
    }
    else
    {
        //std::cout << "recv error" << std::endl;
        return false;
    }
    return true;
}

void Send(int sock,const std::string message)
{
    ssize_t n = send(sock,message.c_str(),message.size(),0);
    if(n < 0)
        std::cout << "send error" << std::endl;
}

// 为了保证每一份数据都能被完美读取，需要进行解码和加码
// length/r/n_x _op _y/r/n
// 进行解码返回运算式子
std::string Decode(std::string& message)
{
    //寻找到第一个分隔符(/r/n)处
    int pos = message.find(SEP);
    //获取length
    int size = atoi(message.substr(0,pos).c_str());
    //剩下的长度
    int content_length = message.size() - pos - 2*SEP_LEN;
    if(content_length >= size)
    {
        //删去式子前的所有
        message.erase(0,pos+SEP_LEN);
        std::string s = message.substr(0,size);
        message.erase(0,size+SEP_LEN);
        return s;
    }
    else
    {
        return "";
    }
}

//加码：给原来的式子前面加上length
std::string Encode(std::string& s)
{
    std::string res = std::to_string(s.size());
    res+=SEP;
    res+=s;
    res+=SEP;
    return res;
}